package com.clickpaas.workinghours.service.Impl;

import com.alibaba.fastjson.JSONObject;
import com.bizcloud.ipaas.tbba4bf83484b4ed2aacba581fbfeac4d.d20210220155135.model.*;
import com.clickpaas.workinghours.common.Response.CommonCode;
import com.clickpaas.workinghours.common.Response.ResponseResult;
import com.clickpaas.workinghours.constant.ConstantFile;
import com.clickpaas.workinghours.entity.*;
import com.clickpaas.workinghours.service.*;
import com.clickpaas.workinghours.utils.DataInfoUtil;
import com.clickpaas.workinghours.utils.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

@Service
@Slf4j
public class ControllerServiceImpl implements ControllerService {
    @Resource
    private ProjectService projectService;
    @Resource
    private OpportunityService opportunityService;
    @Resource
    private CampaignService campaignService;
    @Resource
    private WbsService wbsService;
    @Resource
    private TimeCardService timeCardService;
    @Resource
    private TimeSheetService timeSheetService;
    @Resource
    private TimeCardDateService timeCardDateService;
    @Resource
    private UserService userService;
    @Resource
    private LeadService leadService;

    /**
     * 查询TimeCard数据
     *
     * @param entity
     * @return
     */
    @Override
    public ResponseResult getTimeCardInfo(TimeCardEntity entity) {
        String timeDate = "";
        if (null != entity
                && null != entity.getTimeCardDate()
                && StringUtils.isNotBlank(entity.getTimeCardDate().toString())){
            timeDate = DataInfoUtil.getCurrentMonday(entity.getTimeCardDate().toString());
        }

        //取出日期对应当前一周的数据
        ArrayList<String> weekDays = new ArrayList<>();
        String monday = DataInfoUtil.getCurrentMonday(timeDate);
        int i = 0;
        while (i<7){
            weekDays.add(monday);
            monday = DataInfoUtil.dateAfter(monday);
            i++;
        }
        entity.setTimeCardDate(null);
        List<TimeCardDTO> dataInfo = timeCardService.getDataInfo(entity);
        if (null == dataInfo || dataInfo.size()<=0)return new ResponseResult(CommonCode.FAIL,new ArrayList<>());
        List<TimeCardEntity> timeCardEntities = timeCardService.DataConver(dataInfo);
        if (timeCardEntities.size()<=0)return new ResponseResult(CommonCode.FAIL,new ArrayList<>());


        ArrayList<TimeCardEntity> reList = new ArrayList<>();
        /**
         * 多线程处理数据
         */
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        List<Future<TimeCardEntity>> arrayList = Collections.synchronizedList(new ArrayList<>());
        try {
            timeCardEntities.forEach(timeCardEntity -> {
                TimeCardEntity data = timeCardEntity;
                Future<TimeCardEntity> submit =  executorService.submit(getTimeCardCallable(data, weekDays));
                arrayList.add(submit);
            });
        }finally {
            executorService.shutdown();
            try {
                executorService.awaitTermination(3000,TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                log.info("多线程查询数据异常：【{}】",e);
            }
        }
        if (arrayList.size()<0)return new ResponseResult(CommonCode.FAIL,new ArrayList<>());
        arrayList.forEach(resData -> {
            try {
                reList.add(resData.get());
            } catch (InterruptedException e) {
                log.info("工时对象数据异常：【{}】",e);
            } catch (ExecutionException e) {
                log.info("工时对象数据异常：【{}】",e);
            }
        });
        if (reList.size()>0){
            DataInfoUtil.sortTimeCard(reList);
            return new ResponseResult(CommonCode.SUCCESS,reList);
        }
        return new ResponseResult(CommonCode.FAIL,new ArrayList<>());
    }

    /**
     * 插入TimeCard数据
     *
     * @param entity
     * @return
     */
    @Override
    public ResponseResult insertTimeCardInfo(TimeCardEntity entity) {
        if (null == entity)return new ResponseResult(CommonCode.FAIL,"入库失败");
        TimeCardSaveOrUpdateDataResponseObject dataRep = timeCardService.insertDataInfo(entity);
        if (null == dataRep)return new ResponseResult(CommonCode.FAIL,"入库失败");
        if (StringUtils.isNotBlank(dataRep.getMessage())
                && ConstantFile._MESSAGE.equals(dataRep.getMessage())
                && null != dataRep.getData()){
            if(null == entity.getWorkDate()) return new ResponseResult(CommonCode.SUCCESS,"入库成功");
            List<TimeCardDateEntity> timeCardDateEntities = DataInfoUtil.castList(entity.getWorkDate(), TimeCardDateEntity.class);
            for (TimeCardDateEntity dateEntity: timeCardDateEntities){
                List<RepInsertDataEntity> repInsertDataEntities = DataInfoUtil.castGjsontoList(dataRep.getData(), RepInsertDataEntity.class);
                if (repInsertDataEntities.size()>0){
                    dateEntity.setTimeCard(repInsertDataEntities.get(0).getSaveDataId());
                    timeCardDateService.insertDataInfo(dateEntity);
                }
            }
            return new ResponseResult(CommonCode.SUCCESS,"入库成功");
        }
        return new ResponseResult(CommonCode.FAIL,"入库失败");
    }

    /**
     * 批量插入TimeCard数据
     *
     * @param timeCardEntity
     * @return
     */
    @Override
    public ResponseResult insertBatchTimeCardInfo(List<TimeCardEntity> timeCardEntity) {
        if (null == timeCardEntity || timeCardEntity.size()<=0)return new ResponseResult(CommonCode.FAIL,"批量更新失败");
        List<TimeCardEntity> timeCardEntities = DataInfoUtil.castList(timeCardEntity, TimeCardEntity.class);
        for (TimeCardEntity date : timeCardEntities){
            insertTimeCardInfo(date);
        }
        return new ResponseResult(CommonCode.FAIL,"批量入库成功");
    }

    /**
     * 更新TimeCard数据
     *
     * @param entity
     * @return
     */
    @Override
    public ResponseResult updateTimeCardInfo(TimeCardEntity entity) {
        if (null == entity || StringUtils.isBlank(entity.getQueryId()))
            return new ResponseResult(CommonCode.FAIL,"更新失败");

        TimeCardEntity queryTimeCard = new TimeCardEntity();
        queryTimeCard.setId(entity.getQueryId());
        String timeCardMsg = timeCardService.updateDataInfo(queryTimeCard, entity).getMessage();
        boolean timeCardFlag = false;
        boolean timeCardDateFlag = false;
        if (ConstantFile._MESSAGE.equals(timeCardMsg)){
            timeCardFlag = true;
        }
        if (null != entity.getWorkDate()) {
            List<TimeCardDateEntity> timeCardDateEntities = DataInfoUtil.castList(entity.getWorkDate(), TimeCardDateEntity.class);
            for (TimeCardDateEntity updataEntity : timeCardDateEntities) {
                TimeCardDateEntity queryData = new TimeCardDateEntity();
                queryData.setId(updataEntity.getQueryId());
                String dateMsg = timeCardDateService.updateDataInfo(queryData, updataEntity).getMessage();
                if (!timeCardDateFlag) {
                    if (ConstantFile._MESSAGE.equals(dateMsg)) {
                        timeCardDateFlag = true;
                    }
                }
            }
        }

        if (timeCardFlag || timeCardDateFlag){
            return new ResponseResult(CommonCode.SUCCESS,"更新成功");
        }
        return new ResponseResult(CommonCode.FAIL,"更新失败");
    }

    /**
     * 批量更新TimeCard数据
     *
     * @param timeCardEntity
     * @return
     */
    @Override
    public ResponseResult updateBatchTimeCardInfo(List<TimeCardEntity> timeCardEntity) {
        if (null == timeCardEntity || timeCardEntity.size()<=0)return new ResponseResult(CommonCode.FAIL,"批量更新失败");
        List<TimeCardEntity> timeCardEntities = DataInfoUtil.castList(timeCardEntity, TimeCardEntity.class);
        for (TimeCardEntity date : timeCardEntities){
            updateTimeCardInfo(date);
        }
        return new ResponseResult(CommonCode.SUCCESS,"批量更新成功");
    }

    /**
     * 删除TimeCard数据
     *
     * @param entity
     * @return
     */
    @Override
    public ResponseResult deleteTimeCardInfo(TimeCardEntity entity) {
        if (null == entity)return new ResponseResult(CommonCode.FAIL,"删除失败");
        boolean flag = timeCardService.deleteDataInfo(entity);
        if (flag){
            return new ResponseResult(CommonCode.SUCCESS,"删除成功");
        }
        return new ResponseResult(CommonCode.FAIL,"删除失败");
    }

    /**
     * 查询项目数据
     *
     * @return
     */
    @Override
    public ResponseResult getProjectInfo(ProjectEntity entity) {
        List<PMSprojectDTO> projectInfo = projectService.getProjectInfo(entity);
        if (null == projectInfo || projectInfo.size()<=0) return new ResponseResult(CommonCode.FAIL,new ArrayList<>());
        List<ProjectEntity> projectEntities = projectService.projectDataConver(projectInfo);
        if (null == projectEntities || projectEntities.size()<=0) return new ResponseResult(CommonCode.FAIL,new ArrayList<>());
        return new ResponseResult(CommonCode.SUCCESS,projectEntities);
    }

    /**
     * 查询商机数据
     *
     * @param entity
     * @return
     */
    @Override
    public ResponseResult getOpportunityInfo(OpportunityEntity entity) {
        List<OpportunityDTO> dataInfo = opportunityService.getDataInfo(entity);
        if (null == dataInfo || dataInfo.size()<=0) return new ResponseResult(CommonCode.FAIL,new ArrayList<>());
        List<OpportunityEntity> entities = opportunityService.DataConver(dataInfo);
        if (null == entities || entities.size()<=0) return new ResponseResult(CommonCode.FAIL,new ArrayList<>());
        return new ResponseResult(CommonCode.SUCCESS,entities);
    }

    /**
     * 查询市场活动数据
     *
     * @param entity
     * @return
     */
    @Override
    public ResponseResult getCampaignInfo(CampaignEntity entity) {
        List<CampaignDTO> dataInfo = campaignService.getDataInfo(entity);
        if (null == dataInfo || dataInfo.size()<=0) return new ResponseResult(CommonCode.FAIL,new ArrayList<>());
        List<CampaignEntity> entities = campaignService.DataConver(dataInfo);
        if (null == entities || entities.size()<=0) return new ResponseResult(CommonCode.FAIL,new ArrayList<>());
        return new ResponseResult(CommonCode.SUCCESS,entities);
    }

    /**
     * 查询WBS数据
     *
     * @param projectEntity
     * @return
     */
    @Override
    public ResponseResult getWbsInfo(ProjectEntity projectEntity) {
        List<PMSprojectDTO> projectInfo = projectService.getProjectInfo(projectEntity);
        if (null == projectInfo)return new ResponseResult(CommonCode.FAIL,new ArrayList<>());

        for (PMSprojectDTO data : projectInfo){
            if (StringUtils.isBlank(data.getId()))continue;
            WBSEntity wbsEntity = new WBSEntity();
            wbsEntity.setRelatedProject(data.getId());
            List<WBSDTO> dataInfo = wbsService.getDataInfo(wbsEntity);
            if (null == dataInfo || dataInfo.size()<=0) continue;

            List<WBSEntity> wbsEntities = new ArrayList<>();
            for (WBSDTO wbsData : dataInfo){
                WBSEntity entity = new WBSEntity();
                BeanUtils.copyProperties(wbsData,entity);
                String parentNode = wbsService.findParentNode(wbsData);
                if (null != parentNode && !parentNode.equals(entity.getName())){
                    entity.setParent(parentNode);
                }
                wbsEntities.add(entity);
            }
            if (wbsEntities.size()<=0) return new ResponseResult(CommonCode.FAIL,new ArrayList<>());
            return new ResponseResult(CommonCode.SUCCESS,wbsEntities);
        }
        return new ResponseResult(CommonCode.FAIL,new ArrayList<>());
    }

    /**
     * 查询用户名称
     *
     * @return
     */
    @Override
    public ResponseResult getUserInfo(HttpServletRequest httpServletRequest) {
        String token = httpServletRequest.getHeader("tg-token");
        if (StringUtils.isNotBlank(token)){
            UserEntity userInfo = userService.getUserInfo(token);
            if (null != userInfo){
                return new ResponseResult(CommonCode.SUCCESS,userInfo);
            }
        }
        return new ResponseResult(CommonCode.FAIL,"根据用户token没有查询到数据！");
    }

    /**
     * 查询工时填报主数据
     *
     * @return
     */
    @Override
    public ResponseResult getMainData(HttpServletRequest httpServletRequest) {
        String token = httpServletRequest.getHeader("tg-token");
        Map<Object, Object> mainData = timeCardService.getTimeCardMainData(token);
        if (null != mainData){
            return new ResponseResult(CommonCode.SUCCESS,mainData);
        }
        return new ResponseResult(CommonCode.FAIL,"根据用户token没有查询到数据！");
    }

    public ResponseResult getWeekend(WeekEntity weekEntity){
        String timeDate = "";
        if (null != weekEntity && StringUtils.isNotBlank(weekEntity.getNowadays())){
            timeDate = DataInfoUtil.getCurrentMonday(weekEntity.getNowadays());
        }
        WeekEntity repWeek = new WeekEntity();
        repWeek.setNowadays(DataInfoUtil.getNowDay());
        String day = DataInfoUtil.getCurrentMonday(timeDate);
        int i = 0;
        while (i<7){
            switch (i){
                case 0 : repWeek.setMonday(day);
                case 1 : repWeek.setTuesday(day);
                case 2 : repWeek.setWednesday(day);
                case 3 : repWeek.setThursday(day);
                case 4 : repWeek.setFriday(day);
                case 5 : repWeek.setSaturday(day);
                case 6 : repWeek.setSunday(day);
            }
            day = DataInfoUtil.dateAfter(day);
            i++;
        }
        return new ResponseResult(CommonCode.SUCCESS,repWeek);
    }

    /**
     * 更新Lead线索数据
     *
     * @param entity
     * @return
     */
    @Override
    public ResponseResult updateLeadInfo(LeadEntity entity) {
        if (null == entity) return new ResponseResult(CommonCode.FAIL,"更新失败");

        LeadEntity queryTimeCard = null;
        if (StringUtils.isNotBlank(entity.getQueryId())){
            queryTimeCard.setId(entity.getQueryId());
        }
        String timeCardMsg = leadService.updateDataInfo(queryTimeCard, entity).getMessage();

        if (ConstantFile._MESSAGE.equals(timeCardMsg)){
            return new ResponseResult(CommonCode.SUCCESS,"更新成功");
        }
        return new ResponseResult(CommonCode.FAIL,"更新失败");
    }

    private Callable<TimeCardEntity> getTimeCardCallable(TimeCardEntity data, ArrayList<String> weekDays){
        return new Callable<TimeCardEntity>() {
            @Override
            public TimeCardEntity call() throws Exception {
                //项目
                if (null != data.getRelProject()){
                    ProjectEntity projectEntity = new ProjectEntity();
                    projectEntity.setId(data.getRelProject().toString());
                    List<PMSprojectDTO> projectInfo = projectService.getProjectInfo(projectEntity);
                    if (null != projectInfo && projectInfo.size()>0){
                        data.setRelProject(projectInfo.get(0).getName());
                    }
                }

                //商机
                if (null != data.getRelOpty()){
                    OpportunityEntity opportunityEntity = new OpportunityEntity();
                    opportunityEntity.setId(data.getRelOpty().toString());
                    List<OpportunityDTO> oppDataInfo = opportunityService.getDataInfo(opportunityEntity);
                    if (null != oppDataInfo && oppDataInfo.size()>0){
                        data.setRelOpty(oppDataInfo.get(0).getName());
                    };

                }

                //关联市场活动
                if (null != data.getRelCampaign()){
                    CampaignEntity campaignEntity = new CampaignEntity();
                    campaignEntity.setId(data.getRelCampaign().toString());
                    List<CampaignDTO> campDataInfo = campaignService.getDataInfo(campaignEntity);
                    if (null != campDataInfo && campDataInfo.size()>0){
                        data.setRelCampaign(campDataInfo.get(0).getName());
                    }
                }

                //wbs
                if (null != data.getRelWBS()){
                    WBSEntity wbsEntity = new WBSEntity();
                    wbsEntity.setId(data.getRelWBS().toString());
                    List<WBSDTO> wbsdataInfo = wbsService.getDataInfo(wbsEntity);
                    if (null != wbsdataInfo && wbsdataInfo.size()>0){
                        data.setRelWBS(wbsdataInfo.get(0).getName());
                    }
                }

                //工时类型
                if (null != data.getTimeType()){
                    JSONObject jsonObject = JsonUtil.jsonStrToJson(data.getTimeType());
                    Object name = jsonObject.get("name");
                    if (null != name && StringUtils.isNotBlank(name.toString())){
                        data.setTimeType(name.toString());
                    }
                }
                //工时日期
                if (StringUtils.isNotBlank(data.getId())){
                    List<TimeCardDateEntity> arrayList = Collections.synchronizedList(new ArrayList<>());
                    /**
                     * 多线程处理数据
                     */
                    ExecutorService pooldate = Executors.newCachedThreadPool();
                    CountDownLatch latchdate = new CountDownLatch(weekDays.size());

                    for (String day : weekDays){
                        /**
                         * 开启子线程
                         */
                        Runnable run = new Runnable() {
                            public void run() {
                                try {
                                    TimeCardDateEntity timeCardDateEntity = new TimeCardDateEntity();
                                    timeCardDateEntity.setTimeCard(data.getId());
                                    timeCardDateEntity.setTimeCardDate(day);

                                    List<TimeCardDateDTO> dataInfos = timeCardDateService.getDataInfo(timeCardDateEntity);
                                    if (null != dataInfos && dataInfos.size()>0){
                                        List<TimeCardDateEntity> timeCardDateEntities = timeCardDateService.DataConver(dataInfos);
                                        if (null != timeCardDateEntities && timeCardDateEntities.size()>0){
                                            arrayList.add(timeCardDateEntities.get(0));
                                        }else {
                                            TimeCardDateEntity timeCardDate = new TimeCardDateEntity();
                                            timeCardDate.setTimeCardDate(day);
                                            arrayList.add(timeCardDate);
                                        }
                                    }else {
                                        TimeCardDateEntity timeCardDate = new TimeCardDateEntity();
                                        timeCardDate.setTimeCardDate(day);
                                        arrayList.add(timeCardDate);
                                    }
                                }catch(Exception e){
                                    log.info("多线程转换报错,查询对象是：【{}】,请检查：【{}】",data,e);
                                } finally {
                                    latchdate.countDown();
                                }
                            }
                        };
                        pooldate.execute(run);
                    }try {
                        latchdate.await(10, TimeUnit.SECONDS);
                    } catch (InterruptedException e) {
                        log.info("多线程转换报错,请检查：【{}】",e);
                    }finally {
                        pooldate.shutdown();
                    }
                    arrayList.forEach(arr -> {
                        if (null == arr){
                            System.out.println("工时对象为空"+arrayList);
                        }
                    });
                    if (arrayList.size()>0){
                        DataInfoUtil.sortTimeCardDate(arrayList);
                        data.setTimeCardDate(arrayList);
                    }
                }
                return data;
            }
        };
    }
}
